package com.example.registerapi;

import java.util.*;

/**
 * @author：kangxuan
 * @date：2024/9/30 10:26 AM
 * @desc:
 */
public class RegisterInfoHolder {
    /**
     * 服务器注册信息（存放可以调用的服务信息）
     */
    private static final Map<String, Map<String, RegisterInfo>> SERVER_MAP = new HashMap<>();

    /**
     * 监听的服务注册信息（存放所有的服务信息，当有服务注册时，进行通知）
     * @param name
     * @param ip
     * @param port
     */
    private static final Set<RegisterInfo> LISTEN_SERVER_MAP = new HashSet<>();

    public static final String REQ_CHAIN_TAG_NAME = "REQ_CHAIN_TAG";
    private static final ThreadLocal<String> REQ_CHAIN_TAG_VALUE_HOLDER = new ThreadLocal<>();

    public static String getReqChainTag() {
        String s = REQ_CHAIN_TAG_VALUE_HOLDER.get();
        if (s == null){
            s = UUID.randomUUID().toString();
            setReqChainTag(s);
        }
        return s;
    }

    public static void removeReqChainTag() {
        REQ_CHAIN_TAG_VALUE_HOLDER.remove();
    }

    public static void setReqChainTag(String reqChainTag) {
        REQ_CHAIN_TAG_VALUE_HOLDER.set(reqChainTag);
    }

    public static void addListener(RegisterInfo registerInfo) {
        LISTEN_SERVER_MAP.add(registerInfo);
    }

    public static Set<RegisterInfo> getListeners() {
        return LISTEN_SERVER_MAP;
    }

    /**
     * 注册服务
     * @param name
     * @param ip
     * @param port
     */
    public static void register(String name, String ip, String port) {
        RegisterInfo registerInfo = new RegisterInfo(name, ip, port);
        doRegister(registerInfo);
    }

    private static void doRegister(RegisterInfo registerInfo){
        if (!SERVER_MAP.containsKey(registerInfo.getName())){
            SERVER_MAP.put(registerInfo.getName(),new HashMap<>());
        }
        SERVER_MAP.get(registerInfo.getName()).put(registerInfo.getKey(),registerInfo);
    }

    public static void remove(String name, String ip, String port) {
        RegisterInfo registerInfo = new RegisterInfo(name, ip, port);
        if (SERVER_MAP.containsKey(registerInfo.getName())) {
            SERVER_MAP.get(registerInfo.getName()).remove(new RegisterInfo(name, ip, port).getKey());
        }
    }

    public static List<RegisterInfo> getRegisterInfos(String name) {
        List<RegisterInfo> ret = new ArrayList<>();
        if (SERVER_MAP.containsKey(name)) {
            ret =  SERVER_MAP.get(name).values().stream().toList();
        }else {
            List<RegisterInfo> finalRet = ret;
            SERVER_MAP.entrySet().stream().forEach(entry -> finalRet.addAll(entry.getValue().values()));
        }
        return ret;
    }

    public static List<RegisterInfo> getAllRegisterInfos() {
        return SERVER_MAP.values().stream().flatMap(map -> map.values().stream()).toList();
    }

    public static void addRegisterInfo(List<RegisterInfo> registerInfos) {
        for (RegisterInfo registerInfo : registerInfos) {
            doRegister(registerInfo);
        }
    }
}
